package com.salt.modules.sys.service;

import com.google.common.collect.Lists;
import com.salt.common.service.CrudService;
import com.salt.common.utils.StringUtils;
import com.salt.core.oss.OssTemplate;
import com.salt.core.persistence.Page;
import com.salt.modules.sys.entity.MultiTenant;
import com.salt.modules.sys.entity.Office;
import com.salt.modules.sys.entity.User;
import com.salt.modules.sys.mapper.MultiTenantMapper;
import com.salt.modules.sys.mapper.OfficeMapper;
import com.salt.modules.sys.utils.UserUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 管理用户的租户权限（即查看多个公司的数据）Service
 * @Author salt
 * @Date 2022/1/19
 * @Version 1.0.1
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class MultiTenantService extends CrudService<MultiTenantMapper, MultiTenant> {

    private final OssTemplate ossTemplate;
    private final OfficeMapper officeMapper;
    private final OfficeService officeService;

    public MultiTenant get(String id) {
        if (StringUtils.isNotBlank(id)) {
            MultiTenant multiTenant = mapper.get(id);
            if (StringUtils.isNotBlank(multiTenant.getUser().getPhoto())) {
                multiTenant.getUser().setPhoto(ossTemplate.outerFileLink(multiTenant.getUser().getPhoto()));
            }
            setTenantList(multiTenant);
            return multiTenant;
        }
        return new MultiTenant();
    }

    /**
     * 查询多租户
     * @param multiTenant
     * @return
     */
    public List<Office> findTenants(MultiTenant multiTenant) {
        multiTenant = find(multiTenant);
        setTenantList(multiTenant);
        return multiTenant.getTenantList();
    }

    /**
     * 查询多租户ID
     * @param user
     * @return
     */
    public List<String> findTenantIds(User user) {
        MultiTenant multiTenant = find(new MultiTenant(user));
        if (multiTenant != null) {
            String[] split = multiTenant.getTenants().split(",");
            return Arrays.asList(split);
        }
        return null;
    }


    /**
     * 判断是否为多租户
     * @param user
     * @return
     */
    public Boolean isMultiTenant(User user) {
        return find(new MultiTenant(user))!=null?true:false;
    }

    public MultiTenant find(MultiTenant multiTenant) {
        return mapper.find(multiTenant);
    }


    public Page<MultiTenant> findPage(Page<MultiTenant> page, MultiTenant multiTenant) {
        List<MultiTenant> list = mapper.findList(multiTenant);
        if (list != null && !list.isEmpty()) {
            page.setCount(list.size());
            if (page.getMaxResults() != -1) {
                list = list.subList(page.getFirstResult(), page.getLastResult());
            }
            list.stream().forEach(multitenant -> {
                if (StringUtils.isNotBlank(multitenant.getUser().getPhoto())) {
                    multitenant.getUser().setPhoto(ossTemplate.outerFileLink(multitenant.getUser().getPhoto()));
                }
            });
            page.setList(list);
        }
        return page;
    }

    @Transactional(readOnly = false)
    public void save(MultiTenant multiTenant) {
        setTenants(multiTenant);
        super.save(multiTenant);
    }

    public void setTenantList(MultiTenant multiTenant) {
        String[] split = multiTenant.getTenants().split(",");
        List<String> tenantIds = Arrays.asList(split);
        multiTenant.setTenantList(officeMapper.findByIds(tenantIds));
    }

    private void setTenants(MultiTenant multiTenant) {
        List<Office> tenantList = multiTenant.getTenantList();
        StringBuffer sb = new StringBuffer();
        for (Office office:tenantList) {
            sb.append(office.getId());
            sb.append(",");
        }
        multiTenant.setTenants(sb.toString());
    }

    public Map getTenant(Office office) {
        User user = UserUtils.getUser();
        String tenant = null;
        List<String> tenantIds = null;
        if (user.isAdmin()) {
            List<Office> rootOfficeList = officeService.getChildren("0");
            if (rootOfficeList != null && !rootOfficeList.isEmpty()) {
                tenantIds = Lists.newArrayList();
                for (Office companay:rootOfficeList) {
                    tenantIds.add(companay.getId());
                }
            }
            if (office != null && StringUtils.isNotBlank(office.getId())){
                tenant = office.getId();
            } else {
                tenant = rootOfficeList.get(0).getId();
            }
        } else {
            tenantIds = this.findTenantIds(user);
            if (office != null && StringUtils.isNotBlank(office.getId())){
                tenant = office.getId();
            } else {
                tenant = user.getCompany() != null?user.getCompany().getId():null;
            }
        }
        List<String> ids = null;
        if (tenantIds != null && !tenantIds.isEmpty()) {
            ids = tenantIds.stream().distinct().collect(Collectors.toList());
        }
        Map map = new HashMap<>();
        map.put("tenant", tenant);
        map.put("tenantIds", ids);
        return map;
    }

    public List<String> getTenantIds() {
        User user = UserUtils.getUser();
        return getTenantIds(user);
    }

    public List<String> getTenantIds(User user) {
        List<String> tenantIds = this.findTenantIds(user);
        List<String> ids = null;
        if (tenantIds != null && !tenantIds.isEmpty()) {
            ids = tenantIds.stream().distinct().collect(Collectors.toList());
        }
        return ids;
    }

}
